<?php
namespace Core\CoreComponents\AccountingManager;

require_once(COMPONENTS_DIR . 'AccountingManager/IOperations.php');
require_once(CONTRACTS_DIR . 'operation.entity.php');

/**
* This interface provide all accessible methods on operation module
*
* @method ServiceResponse getOperations($accountId, $startDate, $endDate)
* @method ServiceResponse getOperation($id)
* @method ServiceResponse addOperation($accountId, $label, $type, $status, $paymentMean, $category, $expectedamount, $operationdate, $isRecurring, $realamount = null)
* @method ServiceResponse updateOperation($id, $label, $type, $status, $paymentMean, $category, $expectedamount, $realamount, $operationdate, $isRecurring)
* @method ServiceResponse deleteOperation($id)
* @method ServiceResponse attachBill($operation)
*/
class Operations implements IOperations
{
	/**
	 * @property string BILL_PATH the working space for all bills
	 */
	const BILL_PATH = '/Bills';

	/**
	* Default constructor
	*/
	public function __construct()
	{	
		if(file_exists(__DIR__ . self::BILL_PATH) == false)
		{
			mkdir(__DIR__ . self::BILL_PATH);
		}
	}

	/**
	 * Get all operations from an account
	 * 
	 * @param integer $accountId The account id targeted
	 * @param datetime $startDate The start date to retrieve operations
	 * @param datetime $endDate The end date to retrieve operations
	 *
	 * @return ServiceResponse A service response which contains all operation between $startDate and $endDate provided
	 */
    public function getOperations($accountId, $startDate, $endDate)
	{
		Logger::Info("Service - getOperations $accountId, $startDate, $endDate");
		
		$response = null;
		
		try
		{	
			$session = Session::Instance();
			$session->Open();
		
			$session->CreateCriteria('Operation');
			$session->AddCriteria(Expression::SQL_EQ('Account', $accountId));
			$session->AddCriteria(Expression::SQL_SUPOREQ('Operationdate', $startDate));
			$session->AddCriteria(Expression::SQL_INF('Operationdate', $endDate));
			$result = $session->ListResult();

			$sortedList = array();
			
			if(count($result) > 0)
			{
				foreach($result as $operation)
				{
					//Format the date to display on UI side
					$date = new DateTime($operation->Operationdate);
					$operation->Operationdate = $date->format('d/m/Y');
					$date = new DateTime($operation->ModificationDate);
					$operation->ModificationDate = $date->format('d/m/Y H:i:s');
					$date = new DateTime($operation->CreationDate);
					$operation->CreationDate = $date->format('d/m/Y H:i:s');
					
					//Compute the bill
					if(isset($operation->Bill) && isset($operation->BillExtension) && $operation->Bill != null && $operation->BillExtension != null && $operation->BillExtension != '')
					{
						$tempName = __DIR__ . self::BILL_PATH . "/bill_" . $operation->Id . "." . $operation->BillExtension;
						
						Logger::Info("Bill is generated on $tempName");
						
						if(file_put_contents($tempName, $operation->Bill) == false)
						{
							throw new Exception("There is an error on the bill generation.");
						}
						
						$operation->Bill = $tempName;
					}
					
					array_push($sortedList, $operation);
				}
			}
			
			$response = new ServiceResponse($sortedList);

			$session->Close();
			
			Logger::Info("Service - getOperations finished");
		}
		catch (Exception $ex) 
		{
			$response = ServiceResponse::CreateError($ex);
		}
		
		return $response;
	}
	
	/**
	 * Get an operation by his Id
	 *
	 * @param integer $id The account id targeted
	 *
	 * @return ServiceResponse A service response which return the operation
	 */
    public function getOperation($id)
	{
		Logger::Info("Service - getOperation $id");
		
		$response = null;
		
		try
		{	
			$session = Session::Instance();
			$session->Open();
		
			$result = $session->Load('Operation', $id);
			
			$response = new ServiceResponse($result);

			$session->Close();
			
			Logger::Info("Service - getOperation finished");
		}
		catch (Exception $ex) 
		{
			$response = ServiceResponse::CreateError($ex);
		}
		
		return $response;
	}
	
	/**
	 * Add an operation
	 *
	 * @param integer $accountId The account id targeted
	 * @param string $label The label description
	 * @param integer $type The operation type Credit / Debit.
	 * @param integer $status The operation status
	 * @param integer $paymentMean The operation payment mean
	 * @param Category $category The impacted category 
	 * @param float $expectedamount The expected amount
	 * @param datetime $operationdate The operation date performed on account
	 * @param boolean $isRecurring Is the operation recurring ?
	 * @param float $realamount The real amount performed on the account. This is an optional parameter, for rejected operation case
	 *
	 * @return ServiceResponse A service response which return with the added operation
	 */
	public function addOperation($accountId, $label, $type, $status, $paymentMean, $category, $expectedamount, $operationdate, $isRecurring, $realamount = null)
	{
		Logger::Info("addOperation $accountId, $label, $type, $paymentMean, $status, $category, $expectedamount, $operationdate");
		
		$response = null;
		
		try
		{	
			$session = Session::Instance();
			$session->Open();
			
			$operation = Operation::Create($accountId, $label, $type, $status, $paymentMean, $category, $expectedamount, $operationdate, $isRecurring);
			
			if($realamount != null)
			{
				$operation->Realamount = $realamount;
			}
			
			$result = $session->Save($operation);
			$response = new ServiceResponse($result);

			$session->Close();
			Logger::Info("Operation $accountId, $label, $type, $status, $paymentMean, $category, $expectedamount, $operationdate added");
		}
		catch (Exception $ex) 
		{
			$response = ServiceResponse::CreateError($ex);
		}
		
		return $response;
	}
	
	/**
	 * Update an operation
	 *
	 * @param integer $id The operation id targeted
	 * @param string $label The label description
	 * @param integer $type The operation type Credit / Debit.
	 * @param integer $status The operation status
	 * @param integer $paymentMean The operation payment mean
	 * @param Category $category The impacted category 
	 * @param float $expectedamount The expected amount
	 * @param float $realamount The real amount performed on the account
	 * @param datetime $operationdate The operation date performed on account
	 * @param boolean $isRecurring Is the operation recurring ?
	 *
	 * @return ServiceResponse A service response which return with the updated operation
	 */
	public function updateOperation($id, $label, $type, $status, $paymentMean, $category, $expectedamount, $realamount, $operationdate, $isRecurring)
	{
		Logger::Info("Service - UpdateOperation $id, $label, $type, $status, $category, $expectedamount, $operationdate");
		
		$response = null;
		
		try
		{	
			$session = Session::Instance();
			$session->Open();
			
			$operation = $session->Load('Operation', $id);
			
			$operation->Label = $label;
			$operation->Type = $type;
			$operation->Status = $status;
			$operation->PaymentMean = $paymentMean;
			$operation->Category = $category;
			$operation->Expectedamount = $expectedamount;
			$operation->Realamount = $realamount;
			$operation->Operationdate = $operationdate;
			$operation->IsRecurring = $isRecurring;
			$operation->ModificationDate = date("Y-m-d H:i:s");
			
			$result = $session->Update($operation);
			$response = new ServiceResponse($result);

			$session->Close();
			Logger::Info("Service - Operation $id, $label, $type, $status, $category, $expectedamount, $operationdate updated");
		}
		catch (Exception $ex) 
		{
			$response = ServiceResponse::CreateError($ex);
		}
		
		return $response;
	}
	
	/**
	 * Attach a bill to an operation
	 * 
	 * @param Operation $operation The operation id targeted
	 *
	 * @return ServiceResponse The response contains the modified operation
	 */
	public function attachBill($operation)
	{
		Logger::Info("Service - attachBill $operation->Id");
		
		$response = null;
		
		try
		{	
			$session = Session::Instance();
			$session->Open();
			
			$operation->ModificationDate = date("Y-m-d H:i:s");
			Logger::Info("Service - attachBill $operation->PaymentMean");
			$result = $session->Update($operation);
			$response = new ServiceResponse($result);

			$session->Close();
			Logger::Info("Service - attachBill updated");
		}
		catch (Exception $ex) 
		{
			$response = ServiceResponse::CreateError($ex);
		}
		
		return $response;
	}
	
	/**
	 * Delete an operation
	 *
	 * @param integer $id The operation id targeted
	 * 
	 * @return ServiceResponse The response contains the deleted operation
	 */
    public function deleteOperation($id)
	{
		Logger::Info("deleteOperation $id");
		
		$response = null;
		
		try
		{	
			$session = Session::Instance();
			$session->Open();
			
			$operation = $session->Load('Operation', $id);

			$result = $session->Delete($operation);
			$response = new ServiceResponse($result);

			$session->Close();
			Logger::Info("Operation $id deleted");
		}
		catch (Exception $ex) 
		{
			$response = ServiceResponse::CreateError($ex);
		}
		
		return $response;
	}
	
}

?> 